package com.qijian.maindata.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qijian.common.annotation.Log;
import com.qijian.common.core.controller.BaseController;
import com.qijian.common.core.domain.AjaxResult;
import com.qijian.common.core.domain.entity.SysUser;
import com.qijian.common.core.page.TableDataInfo;
import com.qijian.common.enums.BusinessType;
import com.qijian.common.exception.ServiceException;
import com.qijian.common.utils.DateUtils;
import com.qijian.common.utils.EmailUtil;
import com.qijian.common.utils.SecurityUtils;
import com.qijian.common.utils.StringUtils;
import com.qijian.common.utils.bean.BeanUtils;
import com.qijian.common.utils.mybatis.WhereEntityTool;
import com.qijian.common.utils.poi.ExcelUtil;
import com.qijian.common.utils.sync.KingdeeSynUtils;
import com.qijian.common.utils.uuid.IdUtils;
import com.qijian.maindata.domain.Bom;
import com.qijian.maindata.domain.BomDetail;
import com.qijian.maindata.domain.query.BomQuery;
import com.qijian.maindata.domain.vo.BomDetailVo;
import com.qijian.maindata.domain.vo.BomModel;
import com.qijian.maindata.domain.vo.BomVo;
import com.qijian.maindata.domain.vo.BomVo4App;
import com.qijian.maindata.service.IBomDetailService;
import com.qijian.maindata.service.IBomService;
import com.qijian.maindata.tools.poi.ExcelCustomizationBomMaterial;
import com.qijian.system.domain.SysConfig;
import com.qijian.system.mapper.SysConfigMapper;
import com.qijian.system.service.ISysRoleService;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 生产BOMController
 *
 * @author qijian
 * @date 2021-09-01
 */
@Api(tags = "工艺管理：生产BOM")
@RestController
@RequiredArgsConstructor
@RequestMapping("/maindata/bom")
public class BomController extends BaseController {

    private final IBomService bomService;
    private final IBomDetailService bomDetailService;

    private final ISysRoleService sysRoleService;
    private final SysConfigMapper sysConfigMapper;


    /**
     * 查询生产BOM列表
     */
//    @PreAuthorize("@ss.hasPermi('maindata:bom:list')")
    @GetMapping("/list")
    public TableDataInfo list(BomQuery query, Page<Bom> page) {
        return getDataTable(bomService.pageVo(page, WhereEntityTool.invoke(query)));
    }

    /**
     * 查询生产BOM列表（手机端）
     */
    @GetMapping("/list4app")
    public TableDataInfo list4app(BomQuery query, Page<Bom> page) {
        Page<BomVo4App> bomVoPage = bomService.list4app(page, WhereEntityTool.invoke(query));
        return getDataTable(bomVoPage);
    }

    @GetMapping("/projectlist")
    public TableDataInfo selectVoForProject(BomQuery query, Page<Bom> page) {
        if (null != query.getTransferFromPage() && null != query.getQueryDays()) {
            int days = -query.getQueryDays().intValue();
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, days);
            Date startDate = calendar.getTime();
            String startTime = DateUtils.format(startDate, "yyyy-MM-dd HH:mm:ss");

            QueryWrapper<BomQuery> wrapper = WhereEntityTool.invoke(query);

            wrapper.orderByDesc("mb.lstTime");

            return getDataTable(bomService.selectVoForDESQSLKJ(page, WhereEntityTool.invoke(query), startTime));
        }

        return getDataTable(bomService.selectVoForProject(page, WhereEntityTool.invoke(query)));
    }

    @GetMapping("/classify")
    public TableDataInfo classify() {
        return getDataTable(bomService.classify());
    }

    @PreAuthorize("@ss.hasPermi('maindata:bom:list')")
    @GetMapping("/list/all")
    public TableDataInfo all(BomQuery query) {
        return getDataTable(bomService.vo(WhereEntityTool.invoke(query)));
    }

    @Log(title = "同步BOM", businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermi('maindata:bom:sync')")
    @PostMapping("/sync")
    public AjaxResult sync(@Validated @NotEmpty(message = "参数不能为空！") String json) {
        JSONObject jsonObject = JSONUtil.parseObj(json);
        if (StringUtils.isBlank(jsonObject.getStr("number"))) {
            throw new ServiceException("E01:物料编码为空！");
        }
        String bomType = jsonObject.getStr("bomType");
        if (StringUtils.isBlank(bomType)) {
            throw new ServiceException("E01:BOM类型为空！");
        }
        JSONArray itemJSONArray = KingdeeSynUtils.getItemByNumber(jsonObject.getStr("number"));
        if (itemJSONArray.size() == 0) {
            throw new ServiceException("E01:物料编号错误！");
        }
        JSONArray item = itemJSONArray.getJSONArray(0);
        List<JSONArray> datas = new ArrayList<>(16);
        KingdeeSynUtils.getBom(item.getStr(19), datas);
        if (1 > datas.size()) {
            throw new ServiceException("E01:BOM信息为空！");
        }
        return toAjax(bomService.syncKingdeeBom(item, datas, bomType));
    }

    /**
     * 导出生产BOM列表
     */
    @PreAuthorize("@ss.hasPermi('maindata:bom:export')")
    @Log(title = "生产BOM", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(BomQuery query) {
        return new ExcelUtil<>(Bom.class).exportExcel(bomService.list(WhereEntityTool.invoke(query)), "生产BOM数据");
    }

    /**
     * 获取生产BOM详细信息
     */
    @PreAuthorize("@ss.hasPermi('maindata:bom:query')")
    @GetMapping(value = "/{bomId}")
    public AjaxResult getInfo(@PathVariable("bomId") Long bomId) {
        return AjaxResult.success(bomService.getById(bomId));
    }

    /**
     * 新增生产BOM
     */
    @PreAuthorize("@ss.hasPermi('maindata:bom:add')")
    @Log(title = "生产BOM", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Bom bom) {
        bom.setBomId(IdUtils.singletonSnowId());
        if (StringUtils.isEmpty(bom.getBomCode())) {
            bom.setBomCode("BOM-" + String.format("%06d", bomService.count() + 1));
        }
        bom.setUserId(SecurityUtils.getUserId());
        bom.setNickName(SecurityUtils.getNickName());

        BomDetail bomDetail = new BomDetail();
        bomDetail.setDetailId(bom.getBomId());
        bomDetail.setDetailCode("0");
        bomDetail.setSubCount(0);
        bomDetail.setLevel(0);
        bomDetail.setBomId(bom.getBomId());
        bomDetail.setItemId(bom.getItemId());
        bomDetail.setItemCode(bom.getItemCode());
        bomDetail.setQuantity(1);
        bomDetail.setSort(1);
        bomDetail.setCreateId(SecurityUtils.getUserId());
        bomDetailService.save(bomDetail);
        return toAjax(bomService.save(bom));
    }

    /**
     * 修改生产BOM
     */
    @PreAuthorize("@ss.hasPermi('maindata:bom:edit')")
    @Log(title = "生产BOM", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody BomVo bomVo) {
        if (bomVo.getItemId() != null) {
            BomDetail bomDetail = bomDetailService.getById(bomVo.getBomId());
            bomDetail.setDetailId(bomVo.getBomId());
            bomDetail.setBomId(bomVo.getBomId());
            bomDetail.setItemId(bomVo.getItemId());
            bomDetail.setItemCode(bomVo.getItemCode());
            bomDetail.setDetailCode("0");
            bomDetailService.save(bomDetail);
        }
        Bom one = bomService.getById(bomVo.getBomId());
        Bom bom = new Bom();
        BeanUtils.copyProperties(bomVo, bom);
        JSONObject object = JSONUtil.parseObj(bom.getBomStatus());
        JSONObject o = new JSONObject();
        if (one.getBomTime() != null) {
            o = JSONUtil.parseObj(one.getBomTime());
        }
        o.put(bomVo.getFinishType(), DateUtils.getTime());
        bom.setBomTime(o.toString());
        boolean flag = true;
        for (Object obj : object.values()) {
            flag = (boolean) obj;
            if (!flag) {
                break;
            }
        }
        bomVo.setIsDisabled(!flag);

        List<String> disabledArr = getDisAblePrefixList();

        if ("线路".equals(bomVo.getFinishType())) {

            BomDetailVo detailVo = bomDetailService.getBomDetailLineProcessType(bomVo.getBomId());
            String itemCode = detailVo.getItemCode();

            boolean matchPrefix = CollectionUtils.isNotEmpty(disabledArr) ? disabledArr.stream().filter(pre -> itemCode.contains(pre)).findAny().isPresent() : false;


        }
        return toAjax(bomService.updateById(bom));
    }

    @NotNull
    private List<String> getDisAblePrefixList() {
        SysConfig sysConfig = sysConfigMapper.checkConfigKeyUnique("quality.project-disable-prefix");
        String configStr = null;
        if (null != sysConfig) {
            configStr = sysConfig.getConfigValue();
        }

        List<String> disabledArr = new ArrayList<>();

        if (configStr != null) {
            disabledArr = Arrays.asList(configStr.split(","));
        }
        return disabledArr;
    }


    public void remindMail(BomVo bomVo, List<String> emailList) {

        String subject = "BOM:【" + bomVo.getBomCodeStr() + "】-【" + bomVo.getBomNameStr() + "】工艺线路已完成!";

        List<Object> params = new ArrayList<>(6);
        params.add(subject + " 请及时提交定额申请!");

        List<String> targetEmails = emailList.stream().filter(e -> StringUtils.isNotEmpty(e)).collect(Collectors.toList());

        EmailUtil.sendEmail("BOM线路完成提醒质量", targetEmails, subject, params);

    }


    /**
     * 批量更新BOM
     */
    @Log(title = "批量更新BOM", businessType = BusinessType.UPDATE)
    @PutMapping("/batch")
    public AjaxResult editBOM(@RequestBody BomModel bomModel) {
        if (CollectionUtils.isEmpty(bomModel.getBomIds())) {
            throw new ServiceException("E01:bomId 不存在");
        }
        bomModel.getBomIds().stream().forEach(e -> {
            Bom bom = new Bom();
            bom.setBomId(e);
            bom.setQualityEngineerId(bomModel.getQualityEngineerId());
            bom.setQualityEngineerName(bomModel.getQualityEngineerName());
            bomService.updateById(bom);
        });
        return AjaxResult.success();
    }


    /**
     * 统计质量管理工程师数量
     *
     * @return
     */
    @GetMapping("/countQualityEngineer")
    public AjaxResult countQualityEngineer(@RequestParam(required = false) Boolean qualityManagementGzFilter) {
        int size = bomService.list(new LambdaQueryWrapper<Bom>().
                isNull(Bom::getQualityEngineerName).or().eq(Bom::getQualityEngineerName, "")
                .last(qualityManagementGzFilter != null && qualityManagementGzFilter, " and main_bom.bom_type = 1  and  EXISTS ( select 1 from main_item where main_item.is_del = 0 and main_bom.item_id = main_item.item_id and  main_item.item_code not like '%BL%' )")
        ).size();
        return AjaxResult.success(size);
    }


    @GetMapping("/export/material/{bomId}")
    public void exportMaterial(@PathVariable Long bomId, HttpServletResponse response) {
        new ExcelCustomizationBomMaterial().exportExcel(response, bomService.getBomAllLineProcessItems(bomId));
    }

    /**
     * 删除生产BOM
     */
    @PreAuthorize("@ss.hasPermi('maindata:bom:remove')")
    @Log(title = "生产BOM", businessType = BusinessType.DELETE)
    @DeleteMapping("/{bomIds}")
    public AjaxResult remove(@PathVariable List<Long> bomIds) {
        return toAjax(bomService.removeWithDetails(bomIds));
    }
}
